<?php


declare(strict_types=1);

namespace app\common\trait;

use think\facade\Db;
use think\Model;
use app\common\trait\ResultTrait;

/**
 * 模型 通用操作-增删改查
 */
trait BaseLogicTrait
{
    use ResultTrait;

    protected Model $model;

    /**
     * $options ['alias', 'with', 'has_where', 'raw', 'closure_querys', 'trashed', 'hidden_fields']
     */
    public function list($where = [], $field = '*', $order = [], $paginate = [], $options = []): array
    {
        if (!empty($options['alias'])) {
            $model_query = $this->model->alias($options['alias'])->field($field);
        } else {
            $model_query = $this->model->field($field);
        }

        if (!empty($options['with'])) {
            $model_query->with($options['with']);
        }

        if (!empty($options['has_where'])) {
            foreach ($options['has_where'] as $has_k => $has_v) {
                $model_query->hasWhere($has_k, $has_v);
            }
        }

        if (!empty($options['cache'])) {
            $key = $options['cache']['key'] ?? true;
            $expire = $options['cache']['expire'] ?? null;
            $tag = $options['cache']['tag'] ?? null;
            $cache_always = $options['cache']['cache_always'] ?? false;

            if ($cache_always) {
                $model_query->cacheAlways($key, $expire, $tag);
            } else {
                $model_query->cache($key, $expire, $tag);
            }
        }

        if (!empty($options['raw'])) {
            if (is_array($options['raw'])) {
                foreach ($options['raw'] as $raw_k => $raw_v) {
                    $model_query->whereRaw($raw_k, $raw_v);
                }
            } else {
                $model_query->whereRaw($options['raw']);
            }
        }

        if (!empty($options['closure_querys'])) {
            foreach ($options['closure_querys'] as $cq) {
                $model_query->where($cq);
            }
        }

        if (isset($options['trashed']) && $options['trashed'] != '') {
            if ($options['trashed'] == 'only') {
                $model_query->onlyTrashed();
            } elseif ($options['trashed'] == 'with') {
                $model_query->withTrashed();
            }
        }

        if (!empty($order)) {
            $model_query->order($order);
        }
        if (!empty($where)) {
            $model_query->where($where);
        }

        if ($paginate !== false && empty($paginate)) {
            $request = request();
            $paginate = ['page' => $request->param('page/d', 1), 'list_rows' => $request->param('limit/d', 15)];
        }

        $list = $paginate !== false ? $model_query->paginate($paginate) : $model_query->select();

        if (isset($options['hidden_fields'])) {
            $list->hidden($options['hidden_fields']);
        }

        $list_array = $list->toArray();
        $total = $list_array['total'] ?? count($list_array);
        $re_array = $paginate !== false
            ? $list_array
            : [
                'total' => $total,
                'per_page' => $total,
                'current_page' => 1,
                'last_page' => 1,
                'data' => $list_array,
            ];

        return $this->ok('查询成功', $re_array);

    }


    public function save($data): array
    {
        $model = $this->model::create($data);
        return $model
            ? $this->ok('添加成功', $model)
            : $this->fail('添加失败');
    }
    public function read($data): array
    {
        $model = $this->model::find($data['id']);
        return $model
            ? $this->ok('查询成功', $model)
            : $this->fail('查询失败');
    }

    public function update($data): array
    {
        $model = $this->model::update($data);
        return $model
            ? $this->ok('更新成功', $model)
            : $this->fail('更新失败');
    }

    public function changeDept($data): array
    {
        Db::startTrans();
        try {
            $model_query = $this->model::where('id', 'in', $data['ids'])->field('id,dept_id');
            $list = $model_query->select();
            if (!$list->isEmpty()) {
                foreach ($list as $item) {
                    $item->dept_id = $data['dept_id'];
                    $item->save();
                }
                Db::commit();
                return $this->ok('修改部门成功');
            } else {
                throw new \Exception('无匹配数据');
            }
        } catch (\Exception $e) {
            Db::rollback();
            return $this->fail('修改失败 ' . $e->getMessage());
        }
    }


    /**
     * @param mixed $data ['del_ids', 'force']
     */
    public function delete($data): array
    {
        Db::startTrans();
        try {
            $model_query = $this->model::where('id', 'in', $data['del_ids'])->field('id');

            $list = $model_query->select();
            if (!$list->isEmpty()) {
                if (isset($data['force']) && $data['force'] == 1) {
                    foreach ($list as $item) {
                        $item->force()->delete();
                    }
                } else {
                    foreach ($list as $item) {
                        $item->delete();
                    }
                }

                Db::commit();
                return $this->ok('删除成功');
            } else {
                throw new \Exception('无匹配数据');
            }
        } catch (\Exception $e) {
            Db::rollback();
            return $this->fail('修改失败 ' . $e->getMessage());
        }
    }

    public function getMainAlias(): string
    {
        return isset($this->model) ? class_basename($this->model) : '';
    }
}
